package com.tjhk.java.tech.io;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class LockingMappedFiles {
    static final int LENGTH = 0X8FFFFFF;
    static FileChannel fc;

    public static void main(String[] args) throws IOException {
        fc = new RandomAccessFile("test.dat","rw").getChannel();
        MappedByteBuffer mp = fc.map(FileChannel.MapMode.READ_WRITE,0,LENGTH);
        for (int i = 0; i < LENGTH; i++) {
            mp.put((byte) 'x');
        }
        new LockAndModify(mp,0,0+LENGTH/3);
        new LockAndModify(mp,LENGTH/2,LENGTH/2+LENGTH/4);
    }
    private static class LockAndModify extends Thread{
        private ByteBuffer buffer;
        private int start,end;

        public LockAndModify(ByteBuffer mbb, int start, int end) {
            this.start = start;
            this.end = end;
            mbb.limit(end);
            mbb.position(start);
            buffer = mbb.slice();
            start();
        }

        @Override
        public void run() {
            try {
                FileLock lock = fc.lock(start,end,false);
                System.out.println("Locked: "+start + " to: "+end);
                while (buffer.position() < buffer.limit()-1){
                    buffer.put((byte) (buffer.get()+1));
                }
                lock.release();
                System.out.println("Release Locked: "+start + " to: "+end);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
